<template>
  <div style="height: 24px; width: 100%">
    <el-autocomplete
      v-if="multiple != true"
      v-model="defaultValue"
      v-on="event"
      @focus="focus"
      :fetch-suggestions="querySearchAsync"
      @keyup="keyup"
      teleported
      :disabled="autodisabled || disabled"
      :placeholder="placeholder"
      :value-key="defaultOption.showfield"
      highlight-first-item
      :trigger-on-focus="false"
      :debounce="0"
      @blur="blur"
      :select-when-unmatched="false"
      @select="handleSelect"
      @dblclick="triggerSelect"
      ref="myautoc"
      class="selfcss"
      style="height: 100%; width: 100%"
    >
      <template v-if="showIconDefault" #suffix>
        <slot name="suffix"></slot>
      </template>

      <template #default="{ item }">
        <span
          v-bind:key="field.field"
          v-for="field in defaultOption.showFields"
          :style="'display:inline-block;width:' + field.width + 'px;font-size:12px;'"
          :class="field.class"
        >
          {{ XEUtils.get(item, field.field) }}
        </span>
      </template>

      <template v-if="hasPrepend" #prepend>
        <slot name="prepend"></slot>
      </template>

      <template v-if="hasAppend" #append>
        <slot name="append"></slot>
      </template>
    </el-autocomplete>
    <el-select
      v-if="multiple == true"
      :disabled="autodisabled || disabled"
      v-model="defaultValue"
      multiple
      filterable
      remote
      style="width: 100%; height: 100%"
      reserve-keyword
      :clearable="true"
      :placeholder="placeholder"
      :remote-method="loadAll"
      tag-type="danger"
      :automatic-dropdown="true"
      :loading="loading"
      @visible-change="hideSel"
    >
      <el-option
        v-for="item in options"
        :key="item.value"
        :label="item.label"
        :value="XEUtils.get(item, defaultOption.showfield)"
      >
        <span
          v-bind:key="field.field"
          v-for="field in defaultOption.showFields"
          :style="'display:inline-block;width:' + field.width + 'px;font-size:9px;'"
          :class="field.class"
        >
          {{ XEUtils.get(item, field.field) }}
        </span>
      </el-option>
    </el-select>
  </div>
</template>

<script setup>
import { onMounted, reactive, ref, watch, useSlots, nextTick } from "vue";

import config from "@/config/autocomplete";
import XEUtils from "xe-utils";
import axios from "axios";
const props = defineProps({
  url: {},
  fields: {},
  event: {
    type: Object,
    default: () => {
      return {};
    },
  },
  name: { type: String, default: "" },
  params: {},
  sort: { type: String, default: "" },
  order: { type: String, default: "asc" },
  placeholder: {},
  multiple: {},
  showIcon: { type: Boolean, default: null },
  modelValue: {},
  stopDbClick: { type: Boolean, default: false },
  assign: { type: Object, default: null },
  disabled: {
    type: Boolean,
    default: false,
  },
});
const slots = useSlots();
const hasPrepend = ref(false);
const showIconDefault = ref(props.showIcon);
const hasAppend = ref(false);
const autodisabled = ref(false);
const defaultValue = ref(props.modelValue);
const loading = ref(false);
// const attrs = useAttrs();
const defaultOption = reactive({ showFields: {}, fields: {} });
const myautoc = ref(null);
const selectItem = ref(null);
const emit = defineEmits([
  "select",
  "dblclick",
  "update:modelValue",
  "blur",
  "keyup",
  "focus",
]);
watch(defaultValue, value => {
  emit("update:modelValue", value);
});
watch(
  () => props.showIcon,
  value => {
    showIconDefault.value = value;
  }
);
watch(
  () => props.modelValue,
  value => {
    defaultValue.value = value;
  }
);
var beforeValue = null;
const keyup = e => {
  triggerRemote(e);

  emit("keyup", e);
};

const triggerRemote = async () => {
  if ((defaultValue.value?.trim() ?? "") == "" && beforeValue != defaultValue.value) {
    beforeValue = defaultValue.value;
    emit("select", {});
    return await triggerSelect();
  }
};
const blur = e => {
  let self = myautoc.value;

  emit("blur", e, selectItem.value);
  self.suggestions = [];
};
const focus = e => {
  emit("focus", e, selectItem.value);
};
onMounted(() => {
  if (props.name != "") {
    Object.assign(defaultOption, config[props.name]);
  } else {
    Object.assign(defaultOption, props);
  }
  defaultOption["showFields"] = defaultOption["fields"].filter(item => {
    return item.show;
  });
  nextTick(() => {
    if (typeof slots.prepend != "undefined")
      hasPrepend.value = slots.prepend()[0].children.length > 0;
    if (typeof slots.prepend != "undefined")
      hasAppend.value = slots.append()[0].children.length > 0;
  });
});

const setParams = function () {
  /**
   * [{material_id:material_id}]  先从row中看能不获取material_id
   * 1、能获取  比如：123，那么筛选变：[{material_id:123}]
   * 2、不能获取，就原样[{material_id:material_id}]
   */
  let defaultparams = null;
  let urlparams = [];
  if (typeof props.params === "function") defaultparams = props.params();
  else defaultparams = props.params;
  defaultparams = defaultparams instanceof Array ? defaultparams : [defaultparams];
  defaultparams?.forEach(elm => {
    let urlparam = {};

    for (let k in elm) {
      let row_data = XEUtils.get(props.assign, elm[k]);
      if (props.assign && row_data) {
        urlparam[k] = row_data;
      } else urlparam[k] = elm[k];
    }
    urlparams.push(urlparam);
  });
  defaultOption.url.reSetParam([].concat(defaultOption["params"] ?? null, urlparams));
};
const options = ref([]);
var CancelToken = axios.CancelToken;
var source = CancelToken.source();

const loadAll = async (param = "") => {
  var res = [];
  if (!props.disabled) {
    setParams();
    loading.value = true;
    let filterparam = { filter: [{ fuzzy: { value: param } }] };
    if (props.sord != "") {
      filterparam["sort"] = props.sort;
      filterparam["order"] = props.order;
    }

    if (typeof source === "function") {
      source("终止请求");
    }
    res = await defaultOption.url
      .get(filterparam, {
        cancelToken: new axios.CancelToken(function executor(c) {
          source = c;
        }),
      })
      .then(res => {
        if (typeof res != "undefined") {
          if (typeof res.data.rows == "undefined") {
            return res.data;
          } else {
            return res.data.rows;
          }
        } else {
          return [];
        }
      });
    options.value = res;
    loading.value = false;
  }
  return res;
};

//双击触发搜索！
const triggerSelect = async e => {
  let self = myautoc.value;

  emit("dblclick", e, defaultValue.value);

  if (!props.stopDbClick) {
    self.suggestions = await loadAll(defaultValue.value);
    self.activated = true;
  }
};
const hideSel = function (val) {
  if (val == false) {
    autodisabled.value = true;
    setTimeout(() => {
      autodisabled.value = false;
    }, 100);
  }
};
// const handleIconClick = () => {};
// const click = async () => {
//   if (attrs.modelValue == "") {
//     let self = myautoc.value;

//     self.suggestions = await loadAll(attrs.modelValue);
//     self.activated = true;
//   }
// };
const querySearchAsync = async (queryString, cb) => {
  var result = await loadAll(queryString);
  cb(result);
};
// const handleSelect=null
const handleSelect = item => {
  selectItem.value = item;
  emit("select", item);
};
defineExpose({ triggerSelect });
</script>

<style>
.EditSelf .el-input--small .el-input__wrapper {
  padding-right: 1px;
  height: 24px;
}

.selfcss .el-input__suffix {
  border-top-right-radius: 3px;
  border-bottom-right-radius: 3px;
  width: 22px;
}

.selfcss .el-input__suffix:hover {
  cursor: pointer;
  background: rgb(231, 233, 233);
}

.selfcss .el-input .el-input__icon {
  margin: 1px;
  color: rgb(10, 129, 234);
}

.selfcss .el-input-group__append,
.el-input-group__prepend {
  padding-left: var(--prepend-padding);
  padding-right: var(--prepend-padding);
  width: var(--prepend-width);
}
</style>
